#include "transmissaoarquivo.h"
#include "tela.h"

TransmissaoArquivo::TransmissaoArquivo(FileItem *item)
{
    this->item = item;
    QStringList localizacao = this->item->getLocalizacao();
    this->file = new QFile(Tela::pasta_inicial + this->item->getNome());
    file->open(QIODevice::WriteOnly);

    for (int i = 0; i < localizacao.size(); i++) {
        this->fontes.append(new Peer(localizacao.at(i)));
        connect(this->fontes.at(i), SIGNAL(calculosRealizados()), this, SLOT(peerTerminouCalculo()));
        connect(this->fontes.at(i), SIGNAL(transmissaoFinalizada()), this, SLOT(peerFinalizouTransmissao()));
        this->fontes.at(i)->calcularDadosRede();
    }

    this->gravacaoIniciada = 0;
    this->calculosIniciados = 0;
}

void TransmissaoArquivo::salvarArquivo()
{
    QByteArray dados;
    for (int i = 0; i < this->fontes.size(); i++) {
        if (this->fontes.at(i)->getNumeroOrdem() == i)
            dados.append(this->fontes.at(i)->getDadosRecebidos());
    }
    file->write(dados);
    file->close();
    emit this->transmissaoFinalizada(item->getNome());
}

void TransmissaoArquivo::peerTerminouCalculo()
{
    for (int i = 0; i < this->fontes.size(); i++)
        if (!this->fontes.at(i)->calculosTerminados())
            return;
    if (!calculosIniciados) {
        this->calculosIniciados = true;
        this->iniciarTransmissao();
    }
}

void TransmissaoArquivo::iniciarTransmissao()
{
    if (item->getLocalizacao().size() > 1) {
        QList<float> lista_atraso;
        for (int i = 0; i < this->fontes.size(); i++) {
            int j;
            qDebug () << "atraso: " << this->fontes.at(i)->getAtraso();
            for (j = 0; j < lista_atraso.size() && lista_atraso.at(j) <= this->fontes.at(i)->getAtraso(); j++) {}
            if (j == lista_atraso.size())
                lista_atraso.append(this->fontes.at(i)->getAtraso());
            else
                lista_atraso.insert(j, this->fontes.at(i)->getAtraso());
        }

        for (int i = 0; i < lista_atraso.size(); i++) {
            for (int j = 0; j < this->fontes.size(); j++) {
                if (this->fontes.at(j)->getAtraso() == lista_atraso.at(i))
                    this->fontes.at(i)->setNumeroOrdem(i);
            }
        }

        float velocidade = 0;
        for (int i = 0; i < this->fontes.size(); i++) {
            qDebug () << "velocidade: " << this->fontes.at(i)->getBandaDisponivel();
            velocidade += this->fontes.at(i)->getBandaDisponivel();
        }

        qDebug () << "velocidade total: " << velocidade;

        QList<qint64> pedacos_dados;

        qint64 total_dados = 0;

        for (int i = 0; i < this->fontes.size(); i++) {
            qDebug () << this->fontes.at(i)->getBandaDisponivel();
            qint64 qt_dados = item->getTamanho() * (this->fontes.at(i)->getBandaDisponivel()/velocidade);
            qDebug () << QString::number(qt_dados);
            pedacos_dados.append(qt_dados);
            total_dados += qt_dados;
        }

        qDebug () << total_dados;

        for (int i = 0; total_dados < this->item->getTamanho(); total_dados++) {
            pedacos_dados.replace(i, pedacos_dados.at(i) + 1);
            i++;
            if (i == this->fontes.size())
                i = 0;
        }

        QList<qint64> inicio_transmissao;
        inicio_transmissao.append(0);

        for (int i = 1; i <= pedacos_dados.size(); i++) {
            inicio_transmissao.append(inicio_transmissao.at(i-1) + pedacos_dados.at(i-1));
        }

        qDebug () << "#" + this->item->getNome() +
                     "#" + QString::number(inicio_transmissao.at(0)) +
                     "#" + QString::number(pedacos_dados.at(0)) + "#";

        for (int i = 0; i < this->fontes.size(); i++) {
            qDebug () << "pedido enviado!!!";
            this->fontes.at(i)->enviarMensagem("#" + this->item->getNome() +
                                               "#" + QString::number(inicio_transmissao.at(i)) +
                                               "#" + QString::number(pedacos_dados.at(i)) + "#");
        }
    }

    //apenas uma fonte de dados - nao e necessario PING ou outras medicoes
    else {

        this->fontes.at(0)->enviarMensagem("#" + this->item->getNome() +
                                           "#" + QString::number(0) +
                                           "#" + QString::number(this->item->getTamanho()) + "#");
    }
}

void TransmissaoArquivo::peerFinalizouTransmissao()
{
    for (int i = 0; i < this->fontes.size(); i++)
        if (!this->fontes.at(i)->transmissaoTerminada()) {
            return;
        }

    if (!gravacaoIniciada) {
        this->gravacaoIniciada = true;
        this->salvarArquivo();
    }
}
